grammar Gencfa;

options{
	language=Python;
}

tokens {
	CFGD;
	STATEMENT;
	INIT;
	BG;
	NAME;
	REPLACEMENT;
	LOOP;
	MOD;
	ADJ;
}

@members {
sshape = '';
bground =[]; //background
names=[];	//all rules
rule_name=[];	//a rule
invoc=[];	//body of rule
}	

//NOTE: check optional container

cfdg	:	stm_list
	;
	
stm_list:	(statement)+
	;
	
statement
	:	initialization
	|	background
	|	rule
	;
	
initialization
	:	STARTSHAPE USER_STRING {self.sshape = $USER_STRING.text;}
	;
	
background
	:	BACKGROUND LEFTBRACKET buncha_color_adjustments? RIGHTBRACKET {self.bground.append($buncha_color_adjustments.text);}
	;
	
size	:	SIZE modification
	;
/*	
rule	:	RULE USER_STRING LEFTBRACKET buncha_replacements RIGHTBRACKET
	|	RULE USER_STRING USER_RATIONAL LEFTBRACKET buncha_replacements RIGHTBRACKET
	;
*/

rule
@init{
self.rule_name=[]
print "PARSER: NEW RULE"
}
@after{
self.names.append(self.rule_name);
print "PARSER: END RULE: " + str(self.names);
}
: RULE USER_STRING (USER_RATIONAL)? LEFTBRACKET buncha_replacements? RIGHTBRACKET {self.rule_name.append($USER_STRING.text); print $USER_STRING.text;}
	;

	
buncha_replacements
	:	(replacement)+ 
	;
	
replacement
@init{
self.invoc=[]
print "PARSER: NEW INVOCATION"
}
@after {
self.rule_name.append(self.invoc);
}
	:	USER_STRING modification {self.invoc.append($USER_STRING.text);}					
	|	USER_STRING STAR m1=modification USER_STRING m2=modification 	
	;

/*	
modification
	:	LEFTBRACKET buncha_adjustments? RIGHTBRACKET
	|	LEFTBRACE buncha_adjustments? RIGHTBRACE
	;
*/
	
modification
	:	LEFTBRACKET buncha_adjustments? RIGHTBRACKET
	;
	
buncha_adjustments
	:	(adjustment)+
	;

buncha_color_adjustments
	:	(color_adjustment)+
	;
	
adjustment
	:	ROTATE USER_RATIONAL 					{self.invoc.append(($ROTATE.text, $USER_RATIONAL.text));}			
	|	FLIP USER_RATIONAL					{self.invoc.append(($FLIP.text, $USER_RATIONAL.text));}
	|	XSHIFT USER_RATIONAL					{self.invoc.append(($XSHIFT.text, $USER_RATIONAL.text));}			
	|	YSHIFT USER_RATIONAL					{self.invoc.append(($YSHIFT.text, $USER_RATIONAL.text));}			
	|	ZSHIFT USER_RATIONAL					{self.invoc.append(($ZSHIFT.text, $USER_RATIONAL.text));}			
	|	SIZE USER_RATIONAL					{self.invoc.append(($SIZE.text, $USER_RATIONAL.text));}			
	|	SIZE a1=USER_RATIONAL a2=USER_RATIONAL			{self.invoc.append(($SIZE.text, $a1.text, $a2.text));}
	|	SIZE a1=USER_RATIONAL a2=USER_RATIONAL a3=USER_RATIONAL		{self.invoc.append(($SIZE.text, $a1.text, $a2.text, $a3.text));}
	|	SKEW a1=USER_RATIONAL a2=USER_RATIONAL			{self.invoc.append(($SKEW.text, $a1.text, $a2.text));}
	|	color_adjustment					
	;
	
color_adjustment
	:	HUE USER_RATIONAL			{self.invoc.append(($HUE.text , $USER_RATIONAL.text));}
        |	SATURATION USER_RATIONAL			{self.invoc.append(($SATURATION.text , $USER_RATIONAL.text));}
        |	BRIGHTNESS USER_RATIONAL			{self.invoc.append(($BRIGHTNESS.text , $USER_RATIONAL.text));}
        |	ALPHA USER_RATIONAL				{self.invoc.append(($ALPHA.text , $USER_RATIONAL.text));}
        |	HUE USER_RATIONAL_TARGET			{self.invoc.append(($HUE.text , $USER_RATIONAL_TARGET.text));}
        |	SATURATION USER_RATIONAL_TARGET 			{self.invoc.append(($SATURATION.text , $USER_RATIONAL_TARGET.text));}
        |	BRIGHTNESS USER_RATIONAL_TARGET 			{self.invoc.append(($BRIGHTNESS.text , $USER_RATIONAL_TARGET.text));}
        |	ALPHA USER_RATIONAL_TARGET			{self.invoc.append(($ALPHA.text , $USER_RATIONAL_TARGET.text));}
        |	TARGETHUE USER_RATIONAL			{self.invoc.append(($TARGETHUE.text , $USER_RATIONAL.text));}
        |	TARGETSATURATION USER_RATIONAL			{self.invoc.append(($TARGETSATURATION.text , $USER_RATIONAL.text));}
        |	TARGETBRIGHTNESS USER_RATIONAL			{self.invoc.append(($TARGETBRIGHTNESS.text , $USER_RATIONAL.text));}
        |       TARGETALPHA USER_RATIONAL				{self.invoc.append(($TARGETALPHA.text , $USER_RATIONAL.text));}
        ;

STARTSHAPE
	:	'startshape';
BACKGROUND 
	:	 'background';
	
RULE	:	'rule';

LEFTBRACKET
	:	'{';
	
RIGHTBRACKET
	:	'}';
LEFTBRACE
	:	'[';
RIGHTBRACE
	:	']';
STAR	:	'*';
XSHIFT	:	'x';
YSHIFT	:	'y';
ZSHIFT	:	'z';
SIZE
	:	's' | 'size';
ROTATE
	:	'r' | 'rotate';
BRIGHTNESS
	:	'b' | 'brightness';
HUE
	:	'h' | 'hue';
SATURATION
	:	'sat' | 'saturation';	
FLIP
	:	'f' | 'flip';
SKEW
	:	'skew';	
ALPHA
	:	'a' | 'alpha';	
TARGETHUE
	:	'|hue';
TARGETSATURATION
	:	'|sat';
TARGETBRIGHTNESS
	:	'|brightness';
TARGETALPHA
	:	'|alpha';
	
//INTEGER	:	'0'..'9'+;
//RATIONAL:	'0'..'9'+'.''0'..'9'* | '.''0'..'9'+;
USER_STRING	
	:	('a'..'z' | 'A'..'Z')+;
WHITESPACE
	:	(' '|'\n'|'\t'|'\r'|'\f')+ {$channel = HIDDEN;};
//DIGITS
//	:	'0'..'9'+
//	;
	
USER_RATIONAL
	:	 '-'? '0'..'9' +
	|	 '-'? '0'..'9' '.' ('0'..'9')*
	;

USER_RATIONAL_TARGET
	:	'0'..'9'+'|'
	|	'-''0'..'9'+'|'
	;

